package cn.iocoder.yudao.module.of.service.taskfeedback;

import cn.iocoder.yudao.framework.common.core.SysConstants;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
import cn.iocoder.yudao.module.of.controller.admin.taskfeedback.vo.*;
import cn.iocoder.yudao.module.of.controller.admin.taskhandler.vo.TaskHandlerRespVO;
import cn.iocoder.yudao.module.of.controller.admin.taskinfo.vo.TaskInfoRespVO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskapprovals.TaskApprovalDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskfeedback.TaskFeedbackDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskhandler.TaskHandlerDO;
import cn.iocoder.yudao.module.of.dal.dataobject.taskinfo.TaskInfoDO;
import cn.iocoder.yudao.module.of.dal.mysql.taskfeedback.TaskFeedbackMapper;
import cn.iocoder.yudao.module.of.dal.mysql.taskinfo.TaskInfoMapper;
import cn.iocoder.yudao.module.of.enums.*;
import cn.iocoder.yudao.module.of.service.taskhandler.TaskHandlerService;
import cn.iocoder.yudao.module.of.service.taskinfo.TaskInfoService;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.UserDeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.user.UserDeptMapper;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.of.enums.ErrorCodeConstantsOfTask.*;

/**
 * 任务反馈 Service 实现类
 *
 * @author 超级管理员
 */
@Slf4j
@Service
@Validated
public class TaskFeedbackServiceImpl implements TaskFeedbackService {

    @Resource
    private TaskFeedbackMapper taskFeedbackMapper;
    @Resource
    private TaskInfoMapper taskInfoMapper;
    @Resource
    private TaskInfoService taskInfoService;
    @Resource
    private DeptService deptService;
    @Resource
    private UserDeptMapper userDeptMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private TaskHandlerService taskHandlerService;
    @Resource
    private FileMapper fileMapper;


    /**
     * 分页查询
     *
     * @param req 分页查询
     * @return
     */
    @Override
    public PageResult<TaskFeedbackPageResponseVO> feedbackPage(TaskFeedbackPageReqVO req) {
        // 对应任务的领导才能审核下发
        List<Long> userIds; // 空，则说明时集团领导
        Long userId = WebFrameworkUtils.getLoginUserId();

        List<UserDeptDO> userDeptDOS = userDeptMapper.selectList(UserDeptDO::getUserId, userId);
        UserDeptDO JDDept = userDeptDOS.stream().filter(ud -> ud.getDeptId() == SysConstants.JT_LEADER_DEPT.longValue()).findFirst().orElse(null);
        List<UserRoleDO> userRoleDOS = userRoleMapper.selectListByUserId(WebFrameworkUtils.getLoginUserId());
        UserRoleDO taskAdminRole = userRoleDOS.stream().filter(ur -> ur.getRoleId().equals(SysConstants.TASK_ADMIN_ROLE_ID)).findFirst().orElse(null);

        if (JDDept == null && taskAdminRole == null) {
            // 非集团领导，则需要获得权限id
            userIds = deptService.getDeptOfUserIds();
        } else {
            userIds = null;
        }


        MPJLambdaWrapperX<TaskInfoDO> queryWrapper = taskInfoMapper.getQueryWrapper();
        queryWrapper.distinct();
        queryWrapper.selectAll(TaskInfoDO.class);

        queryWrapper.eq(TaskInfoDO::getTaskLevel, TaskLevelEnum.MASTER_LEVEL.getCode());
        queryWrapper.likeIfPresent(TaskInfoDO::getTaskName, req.getTaskName());
        queryWrapper.eqIfPresent(TaskInfoDO::getTaskFrom, req.getTaskFrom());
        queryWrapper.eqIfPresent(TaskInfoDO::getTaskType, req.getTaskType());
        queryWrapper.eqIfPresent(TaskHandlerDO::getDeptId, req.getDeptId());
        queryWrapper.likeIfPresent(AdminUserDO::getNickname, req.getUserName());
        queryWrapper.eqIfPresent(TaskHandlerDO::getDeptId, req.getSubDeptId());
        queryWrapper.likeIfPresent(AdminUserDO::getNickname, req.getSubUserName());
        queryWrapper.eqIfPresent(TaskApprovalDO::getApprovalStatus, ApprovalStatusEnum.PASS.getStatus()); // 肯定是审批通过的
        if (CollectionUtils.isNotEmpty(userIds)) {
            List<Long> parentTaskByHandlers = getParentTaskByHandlers(userIds);
            queryWrapper.eq(TaskHandlerDO::getHandlerType, HandlerTypeEnum.MASTER_LEVEL.getCode());
            queryWrapper.and(q -> q.in(TaskHandlerDO::getUserId, userIds)
                    .or().in(TaskHandlerDO::getDistributionUserId, userIds)
                    // 根据子任务办理人，找到父任务办理人
                    .or().in(TaskInfoDO::getId, CollectionUtils.isEmpty(parentTaskByHandlers) ? new Object[]{-1} : parentTaskByHandlers.toArray()));
        }

        if (CollectionUtils.isNotEmpty(req.getStartTime()) && req.getStartTime().size() == 2) {
            // 下发时间eq.getStartTime()
            queryWrapper.between(TaskApprovalDO::getApprovalTime, req.getStartTime().get(0), req.getStartTime().get(1));
        }
        if (CollectionUtils.isNotEmpty(req.getEndTime()) && req.getEndTime().size() == 2) {
            queryWrapper.between(TaskInfoDO::getEndTime, req.getEndTime().get(0), req.getEndTime().get(1));
        }

        queryWrapper.innerJoin(TaskHandlerDO.class, TaskHandlerDO::getTaskId, TaskInfoDO::getId);
        queryWrapper.leftJoin(DeptDO.class, DeptDO::getId, TaskHandlerDO::getDeptId);
        queryWrapper.leftJoin(AdminUserDO.class, AdminUserDO::getId, TaskHandlerDO::getUserId);
        queryWrapper.leftJoin(TaskApprovalDO.class, TaskApprovalDO::getTaskId, TaskInfoDO::getId);

        // 处理子任务查询条件
        if (req.getSubTaskDeptId() != null || req.getSubTaskSubDeptId() != null
                || StringUtils.isNotBlank(req.getSubTaskName()) || StringUtils.isNotBlank(req.getSubTaskUserName()) || StringUtils.isNotBlank(req.getSubTaskSubUserName())) {
            List<Long> ids = buildSubTaskQueryWrapper(req, userIds);
            if (CollectionUtils.isNotEmpty(ids)) {
                queryWrapper.in(TaskInfoDO::getId, ids);
            }
        }
        queryWrapper.orderByDesc(TaskInfoDO::getId);

        PageResult<TaskInfoDO> pageResult = taskInfoMapper.selectPage(req, queryWrapper);

        if (pageResult.getTotal() == 0) {
            return PageResult.empty();
        }

        List<TaskFeedbackPageResponseVO> feedbacVOList = buildPageResultList(pageResult.getList(), req, userIds);

        return new PageResult<>(feedbacVOList, pageResult.getTotal());
    }

    /**
     * 构造分页查询结果
     *
     * @param masterTaskInfoList 查询结果
     * @param req                查询条件
     */
    private List<TaskFeedbackPageResponseVO> buildPageResultList(List<TaskInfoDO> masterTaskInfoList, TaskFeedbackPageReqVO req, List<Long> userIds) {
        List<TaskFeedbackPageResponseVO> list = new ArrayList<>();
        Long loginUserId = WebFrameworkUtils.getLoginUserId();
        masterTaskInfoList.forEach(task -> {
            // 当前用户时是否时主任务办理人，若是则子任务相关信息都获取
            List<TaskHandlerRespVO> taskHandler = taskHandlerService.getTaskMainHandler(task.getId());
            // 若果当前人是主任务相关人员，则需要获得所有子任务 ; userIds是空表示是集团领导
            boolean ifMainTaskUser = CollectionUtils.isEmpty(userIds) || taskHandler.stream().anyMatch(handler -> loginUserId.equals(handler.getUserId()) || loginUserId.equals(handler.getDistributionUserId()));
            // 主任务
            TaskFeedbackPageResponseVO vo = buildFeedbackDetailVO(task, userIds, ifMainTaskUser);

            // 获得子任务
            List<TaskInfoDO> subTaskList = buildSubTaskQueryWrapperOfResult(task.getId(), req, userIds, ifMainTaskUser);
            // 按照人分组，子任务可以有多个主办人
            List<TaskFeedbackPageResponseVO> subTaskVOList = subTaskList.stream().map(task2 -> buildFeedbackDetailVO(task2, userIds, ifMainTaskUser)).filter(Objects::nonNull).collect(Collectors.toList());
            vo.setChildren(subTaskVOList);

            list.add(vo);
        });


        return list;
    }

    /**
     * 根据查询条件获得子任务
     *
     * @param masterTaskId 主任务id
     * @param req          请求信息
     * @return 子任务集合
     */
    private List<TaskInfoDO> buildSubTaskQueryWrapperOfResult(Long masterTaskId, TaskFeedbackPageReqVO req, List<Long> userIds, boolean ifMainTaskUser) {
        MPJLambdaWrapperX<TaskInfoDO> queryWrapper = taskInfoMapper.getQueryWrapper();
        queryWrapper.distinct();
        queryWrapper.selectAll(TaskInfoDO.class);
        // 如果子查询条件是空，则不查询，只默认查询主任务
        queryWrapper.eq(TaskInfoDO::getParentId, masterTaskId);
        queryWrapper.eq(TaskInfoDO::getTaskLevel, TaskLevelEnum.SUB_LEVEL.getCode());
        queryWrapper.likeIfPresent(TaskInfoDO::getTaskName, req.getSubTaskName());
        queryWrapper.eqIfPresent(TaskHandlerDO::getDeptId, req.getSubTaskDeptId());
        queryWrapper.eqIfPresent(TaskHandlerDO::getDeptId, req.getSubTaskSubDeptId());
        queryWrapper.likeIfPresent(AdminUserDO::getNickname, req.getSubTaskUserName());
        queryWrapper.likeIfPresent(AdminUserDO::getNickname, req.getSubTaskSubUserName());
        queryWrapper.eqIfPresent(TaskApprovalDO::getApprovalStatus, ApprovalStatusEnum.PASS.getStatus()); // 肯定是审批通过的
        if (CollectionUtils.isNotEmpty(userIds) && !ifMainTaskUser) {
            queryWrapper.eq(TaskHandlerDO::getHandlerType, HandlerTypeEnum.MASTER_LEVEL.getCode());
            queryWrapper.and(q -> q.in(TaskHandlerDO::getUserId, userIds)
                    .or().in(TaskHandlerDO::getDistributionUserId, userIds));
        }

        queryWrapper.leftJoin(TaskHandlerDO.class, TaskHandlerDO::getTaskId, TaskInfoDO::getId);
        queryWrapper.leftJoin(DeptDO.class, DeptDO::getId, TaskHandlerDO::getDeptId);
        queryWrapper.leftJoin(AdminUserDO.class, AdminUserDO::getId, TaskHandlerDO::getUserId);
        queryWrapper.leftJoin(TaskApprovalDO.class, TaskApprovalDO::getTaskId, TaskInfoDO::getId);

        return taskInfoMapper.selectList(queryWrapper);
    }


    /**
     * 构造子任务的查询条件
     *
     * @param req 查询条件
     */
    private List<Long> buildSubTaskQueryWrapper(TaskFeedbackPageReqVO req, List<Long> userIds) {
        MPJLambdaWrapperX<TaskInfoDO> queryWrapper = taskInfoMapper.getQueryWrapper();
        queryWrapper.distinct();
        queryWrapper.select(TaskInfoDO::getParentId);
        // 如果子查询条件是空，则不查询，只默认查询主任务
        queryWrapper.eq(TaskInfoDO::getTaskLevel, TaskLevelEnum.SUB_LEVEL.getCode());
        queryWrapper.likeIfPresent(TaskInfoDO::getTaskName, req.getSubTaskName());
        queryWrapper.eqIfPresent(TaskHandlerDO::getDeptId, req.getSubTaskDeptId());
        queryWrapper.eqIfPresent(TaskHandlerDO::getDeptId, req.getSubTaskSubDeptId());
        queryWrapper.likeIfPresent(AdminUserDO::getNickname, req.getSubTaskUserName());
        queryWrapper.likeIfPresent(AdminUserDO::getNickname, req.getSubTaskSubUserName());
        queryWrapper.eqIfPresent(TaskApprovalDO::getApprovalStatus, ApprovalStatusEnum.PASS.getStatus()); // 肯定是审批通过的
        if (CollectionUtils.isNotEmpty(userIds)) {
            queryWrapper.eq(TaskHandlerDO::getHandlerType, HandlerTypeEnum.MASTER_LEVEL.getCode());
            queryWrapper.and(q -> q.in(TaskHandlerDO::getUserId, userIds)
                    .or().in(TaskHandlerDO::getDistributionUserId, userIds));
        }

        queryWrapper.leftJoin(TaskHandlerDO.class, TaskHandlerDO::getTaskId, TaskInfoDO::getId);
        queryWrapper.leftJoin(DeptDO.class, DeptDO::getId, TaskHandlerDO::getDeptId);
        queryWrapper.leftJoin(AdminUserDO.class, AdminUserDO::getId, TaskHandlerDO::getUserId);
        queryWrapper.leftJoin(TaskApprovalDO.class, TaskApprovalDO::getTaskId, TaskInfoDO::getId);

        List<TaskInfoDO> taskInfoList = taskInfoMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(taskInfoList)) {
            return new ArrayList<>();
        }

        return taskInfoMapper.selectList(queryWrapper).stream().map(TaskInfoDO::getParentId).collect(Collectors.toList());
    }

    /**
     * 根据办理人id获得主任务id集合
     *
     * @param userIds 办理人id集合
     * @return 主任务id集合
     */
    private List<Long> getParentTaskByHandlers(List<Long> userIds) {
        MPJLambdaWrapperX<TaskInfoDO> queryWrapper = taskInfoMapper.getQueryWrapper();
        queryWrapper.distinct();
        queryWrapper.select(TaskInfoDO::getParentId);
        queryWrapper.eq(TaskInfoDO::getTaskLevel, TaskLevelEnum.SUB_LEVEL.getCode());
        queryWrapper.and(q -> q.in(TaskHandlerDO::getUserId, userIds)
                .or().in(TaskHandlerDO::getDistributionUserId, userIds));
        queryWrapper.leftJoin(TaskHandlerDO.class, TaskHandlerDO::getTaskId, TaskInfoDO::getId);

        List<TaskInfoDO> taskInfoList = taskInfoMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(taskInfoList)) {
            return new ArrayList<>();
        }

        return taskInfoMapper.selectList(queryWrapper).stream().map(TaskInfoDO::getParentId).collect(Collectors.toList());
    }


    private TaskFeedbackPageResponseVO buildFeedbackDetailVO(TaskInfoDO task, List<Long> userIds, boolean ifMainTaskUser) {
        Long userId = WebFrameworkUtils.getLoginUserId();
        // 这里是获得单个任务的详情，如论主任务还是子任务，都会单独获取，若是子任务相关人员，只能获得自己的

        TaskFeedbackPageResponseVO vo = new TaskFeedbackPageResponseVO();
        BeanUtils.copyProperties(task, vo);
        vo.setStatusName(TaskStatusEnum.valueOf(vo.getStatus(), task.getTaskLevel()));

        List<TaskHandlerRespVO> taskHandler = taskHandlerService.getTaskMainHandler(task.getId());
        // 子任务需要和用户匹配
        if (Objects.equals(task.getTaskLevel(), TaskLevelEnum.SUB_LEVEL.getCode()) && !ifMainTaskUser) {
            taskHandler = taskHandler.stream().filter(handler -> userIds.contains(handler.getUserId()) || userIds.contains(handler.getDistributionUserId())).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(taskHandler)) {
            return null;
        }
        vo.setTaskHandlerList(taskHandler);

        if (CollectionUtils.isNotEmpty(task.getTaskAttachment())) {
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, task.getTaskAttachment());
            vo.setTaskAttachmentList(fileDOS);
        }
        if (CollectionUtils.isNotEmpty(task.getTaskDocFile())) {
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, task.getTaskDocFile());
            vo.setTaskDocFileList(fileDOS);
        }

        // 拼装返回结果，修改状态码，若子任务多个，确保用户，可以反馈，审核
        /*LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskFeedbackDO::getTaskId, task.getId());
        //结合当前用户是否反馈过
        queryWrapper.eq(TaskFeedbackDO::getFeedbackUserId, userId);
        queryWrapper.and(q -> q.eq(TaskFeedbackDO::getFeedbackUserId, userId)
                .or().eq(TaskFeedbackDO::getFeedbackUserId, handlerRespVO.getDistributionUserId()));*/


        // 分页不需要获得反馈信息，具体反馈信息需要单独走接口：getTaskFeedbackDetail or getTaskFeedbackInfo
        /*if (CollectionUtils.isNotEmpty(task.getTaskAttachment())) {
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, task.getTaskAttachment());
            vo.setTaskAttachmentList(fileDOS);
        }
        if (CollectionUtils.isNotEmpty(task.getTaskDocFile())) {
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, task.getTaskDocFile());
            vo.setTaskDocFileList(fileDOS);
        }

        LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskFeedbackDO::getTaskId, task.getId());
        //结合当前用户是否反馈过
        queryWrapper.eq(TaskFeedbackDO::getFeedbackUserId, userId);
        TaskFeedbackDO taskFeedbackDO = taskFeedbackMapper.selectOne(queryWrapper);
        vo.setTaskId(task.getId());
        if (taskFeedbackDO != null) {
            BeanUtils.copyProperties(taskFeedbackDO, vo);
            if (CollectionUtils.isNotEmpty(taskFeedbackDO.getFeedbackAttachment())) {
                List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, taskFeedbackDO.getFeedbackAttachment());
                vo.setFeedbackAttachmentList(fileDOS);
            }
        }*/
        return vo;
    }

    /**
     * 任务反馈
     *
     * @param createReqVO 反馈信息
     */
    @Override
    public void submitTaskFeedback(TaskFeedbackSaveReqVO createReqVO) {
        Long userId = WebFrameworkUtils.getLoginUserId();

        TaskInfoDO taskInfoDO = taskInfoMapper.selectById(createReqVO.getTaskId());
        if (taskInfoDO == null) {
            log.error("【任务反馈】任务不存在, 任务id={}", createReqVO.getTaskId());
            throw exception(TASK_FEEDBACK_NOT_EXISTS);
        }
        // 判断当前用户是否有权限反馈,办理人才可以反馈
        List<TaskHandlerRespVO> taskHandler = taskHandlerService.getTaskMainHandler(taskInfoDO.getId());
        boolean ifMainTaskUser = taskHandler.stream().anyMatch(handler -> userId.equals(handler.getUserId()) || userId.equals(handler.getDistributionUserId()));
        if (!ifMainTaskUser) {
            log.error("【任务反馈】无权限, 任务id={}, userId={}", createReqVO.getTaskId(), userId);
            throw exception(TASK_FEEDBACK_NOT_PERMISSION);
        }

        // 子任务都【反馈&审核&二次审核通过】后，主任务才可以反馈
        if (Objects.equals(taskInfoDO.getTaskLevel(), TaskLevelEnum.MASTER_LEVEL.getCode())) {
            MPJLambdaWrapperX<TaskFeedbackDO> queryWrapper = new MPJLambdaWrapperX<>();
            queryWrapper.select(TaskFeedbackDO::getId);
            queryWrapper.leftJoin(TaskInfoDO.class, TaskInfoDO::getId, TaskFeedbackDO::getTaskId);
            queryWrapper.eq(TaskInfoDO::getTaskLevel, TaskLevelEnum.SUB_LEVEL.getCode());
            queryWrapper.eq(TaskInfoDO::getParentId, createReqVO.getTaskId());
            queryWrapper.eq(TaskFeedbackDO::getFeedbackStatus, FeedbackStatusEnum.HAS_FEEDBACK.getCode());
            queryWrapper.eq(TaskFeedbackDO::getApprovalStatus, ApprovalStatusEnum.PASS.getStatus());
            queryWrapper.eq(TaskFeedbackDO::getApproval2Status, ApprovalStatusEnum.PASS.getStatus());

            // 获得所有子任务中主办人个数，子任务主办支持多个
            MPJLambdaWrapperX<TaskInfoDO> taskQueryWrapper = new MPJLambdaWrapperX<>();
            taskQueryWrapper.rightJoin(TaskHandlerDO.class, TaskHandlerDO::getTaskId, TaskInfoDO::getId);
            taskQueryWrapper.eq(TaskInfoDO::getParentId, createReqVO.getTaskId());
            Long subTaskCount = taskInfoMapper.selectCount(taskQueryWrapper);

            Long feedbackCount = taskFeedbackMapper.selectCount(queryWrapper);
            // 子任务不为0 && 子任务反馈个数小于子任务个数 则不能反馈
            if (!Objects.equals(subTaskCount, 0L) && (feedbackCount < subTaskCount)) {
                log.error("【任务反馈】子任务未全部反馈且审核,主任务无法反馈, 任务id={}", createReqVO.getTaskId());
                throw exception(SUB_TASK_NOT_ALL_FEEDBACK);
            }
        }


        // 插入
        TaskFeedbackDO taskFeedback = BeanUtils.toBean(createReqVO, TaskFeedbackDO.class);
        taskFeedback.setFeedbackUserId(userId);
        taskFeedback.setFeedbackStatus(FeedbackStatusEnum.HAS_FEEDBACK.getCode());
        taskFeedback.setFeedbackTime(LocalDateTime.now());

        if (isTaskFeedbackExists(createReqVO.getTaskId(), userId)) {
            LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TaskFeedbackDO::getTaskId, createReqVO.getTaskId());
            queryWrapper.eq(TaskFeedbackDO::getFeedbackUserId, userId);
            taskFeedbackMapper.update(taskFeedback, queryWrapper);
        } else {
            taskFeedbackMapper.insert(taskFeedback);
        }

        taskInfoMapper.updateStatus(createReqVO.getTaskId(), TaskStatusEnum.NO_CONFIRMED, false);

    }

    /**
     * 获得任务反馈详情
     * <p>
     * 都必须含主任务
     * 子任务，反馈自己反馈的内容即可
     * 主任务，反馈所有子任务，子任务涉及多个主办理人
     *
     * @param taskId 任务id
     * @return
     */
    @Override
    public TaskFeedbackDetailVO getTaskFeedbackDetail(Long taskId) {

        TaskFeedbackDetailVO resVO = new TaskFeedbackDetailVO();
        List<SubTaskInfoFeedbackVO> subTaskInfoFeedbackList = new ArrayList<>();
        TaskInfoRespVO masterTaskVO;
        // 获得当前任务
        TaskInfoRespVO taskInfoVO = taskInfoService.getTaskDetail(taskId);
        if (Objects.equals(taskInfoVO.getTaskLevel(), TaskLevelEnum.MASTER_LEVEL.getCode())) {
            //主任务
            // 1.获得所有子任务详情
            masterTaskVO = taskInfoVO;

            List<TaskInfoRespVO> subTaskDetailList = taskInfoService.getSubTaskDetail(taskInfoVO.getId());
            subTaskInfoFeedbackList = subTaskDetailList.stream().map(subTask -> {
                SubTaskInfoFeedbackVO subTaskInfoFeedbackVO = new SubTaskInfoFeedbackVO();
                subTaskInfoFeedbackVO.setSubTaskInfo(subTask);

                subTaskInfoFeedbackVO.setFeedBackList(getTaskFeedbackInfo(taskId));

                return subTaskInfoFeedbackVO;
            }).collect(Collectors.toList());

        } else {
            // 从任务
            // 1.先获得主任务
            masterTaskVO = taskInfoService.getTaskDetail(taskInfoVO.getParentId());
            SubTaskInfoFeedbackVO subTaskInfoFeedbackVO = new SubTaskInfoFeedbackVO();
            subTaskInfoFeedbackVO.setSubTaskInfo(taskInfoVO);

            // 反馈信息
            List<TaskFeedbackSampleVO> feedbackSampleVOS = getTaskFeedbackInfo(taskId);

            subTaskInfoFeedbackVO.setFeedBackList(feedbackSampleVOS);
            subTaskInfoFeedbackList.add(subTaskInfoFeedbackVO);
        }

        resVO.setMasterTaskInfo(masterTaskVO);
        resVO.setSubTaskInfoList(subTaskInfoFeedbackList);

        return resVO;
    }

    /**
     * 获得任务反馈详情
     * <p>
     * 结合权限，例如多个主办部门时，只能查看自己部门的
     *
     * @param taskId 任务id
     * @return 任务反馈详情
     */
    @Override
    public List<TaskFeedbackSampleVO> getTaskFeedbackInfo(Long taskId) {
        List<Long> userIds; // 空，则说明时集团领导
        Long userId = WebFrameworkUtils.getLoginUserId();

        List<UserDeptDO> userDeptDOS = userDeptMapper.selectList(UserDeptDO::getUserId, userId);
        UserDeptDO JDDept = userDeptDOS.stream().filter(ud -> ud.getDeptId() == SysConstants.JT_LEADER_DEPT.longValue()).findFirst().orElse(null);
        if (JDDept == null) {
            // 非集团领导，则需要获得权限id
            userIds = deptService.getDeptOfUserIds();
        } else {
            userIds = null;
        }

        // 获得主任务id
        Long masterTaskId;
        TaskInfoDO taskInfoDO = taskInfoMapper.selectById(taskId);
        if (Objects.equals(taskInfoDO.getTaskLevel(), TaskLevelEnum.MASTER_LEVEL.getCode())) {
            masterTaskId = taskId;
        } else {
            masterTaskId = taskInfoDO.getParentId();
        }

        // 获得主任务主办人
        List<TaskHandlerRespVO> topTaskHandlerList = taskHandlerService.getTaskMainHandler(masterTaskId);

        List<TaskHandlerRespVO> mainHandlerList = taskHandlerService.getTaskMainHandler(taskId);

        // 判斷是否是主任的主办的人员，主办也有权限
        boolean ifMainTaskUser = CollectionUtils.isEmpty(userIds) || topTaskHandlerList.stream().anyMatch(handler -> userId.equals(handler.getUserId()) || userId.equals(handler.getDistributionUserId()));


        if (CollectionUtils.isNotEmpty(userIds) && !ifMainTaskUser) {
            // 根据用户权限获得
            mainHandlerList = mainHandlerList.stream()
                    .filter(item -> userIds.contains(item.getUserId()) || userIds.contains(item.getDistributionUserId())).collect(Collectors.toList());
        }

        // 获取任务反馈详情
        return mainHandlerList.stream()
                .map(this::getTaskFeedbackInfoByHandlerRespVO)
                .filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 反馈审核(子)、确认(主)
     *
     * @param req 审核信息
     */
    @Override
    public void approval(TaskFeedbackApprovalReqVO req) {
        TaskInfoDO taskInfoDO = taskInfoMapper.selectById(req.getTaskId());
        if (taskInfoDO == null) {
            log.error("【反馈审核确认】任务不存在, 任务id={}", req.getTaskId());
            throw exception(TASK_INFO_NOT_EXISTS);
        }

        // 主任务确认: 主人物反馈后,才可以审核: 主人物的反馈前提是子任务都反馈且所有子任务都审核通过
        // 所以若是主任务,仅仅需要判断主任务是否反馈过即可,子任务也相同,都反馈过就可以审核

        Long userId = WebFrameworkUtils.getLoginUserId();

        // 获取反馈人,及任务负责人(接口人)
        List<TaskHandlerRespVO> taskHandler = taskHandlerService.getTaskMainHandler(req.getTaskId());

        TaskHandlerRespVO taskHandlerVO = taskHandler.stream().filter(item -> item.getUserId().equals(userId)).findFirst().orElse(null);
        if (taskHandlerVO == null) {
            throw exception(TASK_FEEDBACK_APPROVAL_NO_PERMISSION);
        } else {
            // 前端没有传递反馈人,则设置默认为反馈人
            if (taskHandlerVO.getDistributionUserId() != null) {
                req.setFeedbackUserId(taskHandlerVO.getDistributionUserId());
            } else {
                // 没有设置代办人，则本人审核
                req.setFeedbackUserId(taskHandlerVO.getUserId());
            }
        }

//        TaskHandlerRespVO taskHandlerVO = taskHandler.stream()
//                .filter(item -> item.getDistributionUserId().equals(req.getFeedbackUserId()) || item.getUserId().equals(req.getFeedbackUserId())).findFirst().orElse(new TaskHandlerRespVO());

        // 反馈后才可以审核
        if (!isTaskFeedbackExists(req.getTaskId(), taskHandlerVO.getDistributionUserId() != null ? taskHandlerVO.getDistributionUserId() : taskHandlerVO.getUserId())) {
            log.error("【审核确认】任务反馈后, 才可以审核, 任务id={}", req.getTaskId());
            throw exception(TASK_NOT_FEEDBACK);
        }

        // 鉴定当前人是否有权审批
        // 任务审核人: 若有接口人,则是办理人,否则是办理人领导
        checkPermission(userId, taskHandlerVO);

        TaskFeedbackDO taskFeedback = BeanUtils.toBean(req, TaskFeedbackDO.class);
        taskFeedback.setApprovalUserId(userId);
        taskFeedback.setApprovalTime(LocalDateTime.now());

        LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskFeedbackDO::getTaskId, req.getTaskId());
        queryWrapper.eq(TaskFeedbackDO::getFeedbackUserId, req.getFeedbackUserId());// 需要反馈人
        int update = taskFeedbackMapper.update(taskFeedback, queryWrapper);
        if (update == 0) {
            log.error("【任务审核】异常, 任务id={}，任务反馈人={}, 任务审核人={}", req.getTaskId(), req.getFeedbackUserId(), userId);
            throw exception(TASK_APPROVAL_ERR);
        }

        if (update > 0) {
            taskInfoMapper.updateStatus(req.getTaskId(), req.getApprovalStatus() == 2 ? TaskStatusEnum.APPROVAL : TaskStatusEnum.NO_APPROVAL, false);
        }

    }

    /**
     * 主任务办理人对子任务二次确认
     *
     * @param req 审批信息
     */
    @Override
    public void approval2(TaskFeedbackApprovalReqVO req) {
        TaskInfoDO taskInfoDO = taskInfoMapper.selectById(req.getTaskId());
        if (taskInfoDO == null) {
            log.error("【二次审核确认】任务不存在, 任务id={}", req.getTaskId());
            throw exception(TASK_INFO_NOT_EXISTS);
        }
        if (Objects.equals(taskInfoDO.getTaskLevel(), TaskLevelEnum.MASTER_LEVEL.getCode())) {
            log.error("【二次审核确认】不能对主任务二次审核, 任务id={}", req.getTaskId());
            throw exception(SUB_TASK_APPROVALS2_ONLY);
        }
        Long userId = WebFrameworkUtils.getLoginUserId();
        // 二次审核，用户为主任务办理人，且所有子任务都已经审核过了
        List<TaskHandlerRespVO> taskMainHandler = taskHandlerService.getTaskMainHandler(taskInfoDO.getParentId());

        Long taskMainHandlerId = taskMainHandler.get(0).getDistributionUserId() != null
                ? taskMainHandler.get(0).getDistributionUserId() : taskMainHandler.get(0).getUserId();

        if (!Objects.equals(userId, taskMainHandlerId)) {
            log.error("【二次审核确认】用户无权二次审核此任务,需主任务主办人审核, 任务id={}， userId={}", req.getTaskId(), userId);
            throw exception(TASK_FEEDBACK_APPROVAL_NO_PERMISSION);
        }

        // 所有子任务都已经审核过了，才可以二次审核
        /*LambdaQueryWrapper<TaskInfoDO> query = new LambdaQueryWrapper<>();
        query.eq(TaskInfoDO::getParentId, taskInfoDO.getParentId());
        List<TaskInfoDO> childTask = taskInfoMapper.selectList(query);
        List<Long> childTaskIds = childTask.stream().map(item -> item.getId()).collect(Collectors.toList());*/

        LambdaQueryWrapper<TaskFeedbackDO> query = new LambdaQueryWrapper<>();
        query.in(TaskFeedbackDO::getTaskId, req.getTaskId());
        List<TaskFeedbackDO> taskFeedbackList = taskFeedbackMapper.selectList(query);
        if (CollectionUtils.isEmpty(taskFeedbackList)) {
            log.error("【二次审核确认】任务暂未一次审核通过, 任务id={}", req.getTaskId());
            throw exception(TASK_NO_APPROVAL_ERR);
        }
        // 必须都是审核过
        long count = taskFeedbackList.stream().filter(item -> Objects.equals(item.getApprovalStatus(), ApprovalStatusEnum.PASS.getStatus())).count();
        if (taskFeedbackList.size() != count) {
            log.error("【二次审核确认】任务发现有未审核通过的, 任务id={}", req.getTaskId());
            throw exception(TASK_APPROVAL2_ERR);
        }


        TaskFeedbackDO taskFeedback = new TaskFeedbackDO();
        taskFeedback.setApproval2UserId(userId);
        taskFeedback.setApproval2Status(req.getApprovalStatus());
        taskFeedback.setApproval2Content(req.getApprovalContent());
        taskFeedback.setApproval2Time(LocalDateTime.now());

        LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskFeedbackDO::getTaskId, req.getTaskId());
//        queryWrapper.eq(TaskFeedbackDO::getFeedbackUserId, req.getFeedbackUserId());// 需要反馈人，二次审核批量审核
        int update = taskFeedbackMapper.update(taskFeedback, queryWrapper);

        if (update > 0) {
            taskInfoMapper.updateStatus(req.getTaskId(), req.getApprovalStatus() == 2 ? TaskStatusEnum.APPROVAL2 : TaskStatusEnum.NO_APPROVAL2, false);
        }
    }

    /**
     * 鉴定当前人是否有权审批
     *
     * @param userId        当前用户
     * @param taskHandlerVO 任务办理人信息
     */
    private void checkPermission(Long userId, TaskHandlerRespVO taskHandlerVO) {
        // 获得任务办理人领导(任务审核人): 若有接口人,则是办理人,否则是办理人领导
        if (taskHandlerVO.getDistributionUserId() != null) {
            if (!Objects.equals(userId, taskHandlerVO.getUserId())) {
                log.error("【审核确认】当前用户无权限审批, 任务id={}, userId={}", taskHandlerVO.getTaskId(), userId);
                throw exception(TASK_FEEDBACK_APPROVAL_NO_PERMISSION);
            }
        } else {
            // 获得用户领导
            Long deptLeaderId = deptService.getLeaderId(taskHandlerVO.getDeptId());
            if (!Objects.equals(userId, deptLeaderId)) {
                log.error("【审核确认】当前用户无权限审批, 任务id={}, userId={}", taskHandlerVO.getTaskId(), userId);
                throw exception(TASK_FEEDBACK_APPROVAL_NO_PERMISSION);
            }
        }
    }

    /**
     * 判断任务反馈是否存在
     *
     * @param taskId 任务id
     * @return 是否存在
     */
    private boolean isTaskFeedbackExists(Long taskId, Long userId) {
        LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskFeedbackDO::getTaskId, taskId);
        queryWrapper.eq(TaskFeedbackDO::getFeedbackUserId, userId);

        return taskFeedbackMapper.exists(queryWrapper);
    }

    /**
     * 获得任务的反馈信息
     *
     * @return
     */
    private TaskFeedbackSampleVO getTaskFeedbackInfoByHandlerRespVO(TaskHandlerRespVO handlerRespVO) {

        MPJLambdaWrapper<TaskFeedbackDO> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectAll(TaskFeedbackDO.class);
        queryWrapper.selectAs(DeptDO::getName, TaskFeedbackSampleVO::getDeptName);
        queryWrapper.selectAs(DeptDO::getId, TaskFeedbackSampleVO::getDeptId);
        queryWrapper.selectAs(AdminUserDO::getNickname, TaskFeedbackSampleVO::getFeedbackUserName);
        queryWrapper.leftJoin(AdminUserDO.class, AdminUserDO::getId, TaskFeedbackDO::getFeedbackUserId);
        queryWrapper.leftJoin(TaskHandlerDO.class,
                on -> on.eq(TaskHandlerDO::getTaskId, TaskFeedbackDO::getTaskId)
                        .eq(TaskHandlerDO::getDistributionUserId, TaskFeedbackDO::getFeedbackUserId));
        queryWrapper.leftJoin(DeptDO.class, DeptDO::getId, TaskHandlerDO::getDeptId);


        queryWrapper.eq(TaskFeedbackDO::getTaskId, handlerRespVO.getTaskId());
        queryWrapper.and(q -> q.eq(TaskFeedbackDO::getFeedbackUserId, handlerRespVO.getUserId())
                .or().eq(TaskFeedbackDO::getFeedbackUserId, handlerRespVO.getDistributionUserId()));

        TaskFeedbackSampleVO vo = taskFeedbackMapper.selectJoinOne(TaskFeedbackSampleVO.class, queryWrapper);
        if (vo == null) {
            return null;
        }
        // 添加附件
        if (CollectionUtils.isNotEmpty(vo.getFeedbackAttachment())) {
            List<FileDO> fileDOS = fileMapper.selectList(FileDO::getId, vo.getFeedbackAttachment());
            vo.setFeedbackAttachmentList(fileDOS);
        }

        return vo;
    }

    /**
     * 判断任务反馈是否存在
     *
     * @param taskId 任务id
     * @return 是否存在
     */
    private boolean isTaskFeedbackApprovalExists(Long taskId, Long userId) {
        LambdaQueryWrapper<TaskFeedbackDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskFeedbackDO::getTaskId, taskId);
        queryWrapper.eq(TaskFeedbackDO::getApprovalUserId, userId);

        return taskFeedbackMapper.exists(queryWrapper);
    }

    /**
     * 判断子任务是否全部审核
     * <p>
     * 子任务的主办人均审核
     * 子任务的主本人支持多个
     *
     * @param taskId 主任务id
     * @return 是否存在
     */
    private boolean isSubTaskAllFeedback(Long taskId) {
        // 若没有子任务，直接返回true
        if (taskInfoMapper.selectList(new LambdaQueryWrapper<TaskInfoDO>().eq(TaskInfoDO::getParentId, taskId)).isEmpty()) {
            System.err.println("【判断子任务是否全部审核】没有子任务，直接返回true");
            return true;
        }

        MPJLambdaWrapperX<TaskFeedbackDO> queryWrapper = new MPJLambdaWrapperX<>();
        queryWrapper.selectAll(TaskFeedbackDO.class);
        queryWrapper.eq(TaskHandlerDO::getTaskId, taskId);
        queryWrapper.eq(TaskHandlerDO::getHandlerType, HandlerTypeEnum.MASTER_LEVEL.getCode());
        queryWrapper.in(TaskHandlerDO::getTaskId, taskInfoMapper.selectList(new LambdaQueryWrapper<TaskInfoDO>().eq(TaskInfoDO::getParentId, taskId)));
        queryWrapper.rightJoin(TaskHandlerDO.class, TaskHandlerDO::getTaskId, TaskFeedbackDO::getTaskId);

        List<TaskFeedbackDO> taskFeedbackList = taskFeedbackMapper.selectList(queryWrapper);

        long count = taskFeedbackList.stream().filter(item -> Objects.equals(item.getApprovalStatus(), ApprovalStatusEnum.PASS.getStatus())).count();
        return count == taskFeedbackList.size();
    }

}